package de.uni_bremen.exceptions.oops;

class ReturnStatement extends Statement
{
	MethodDeclaration	method;
	
	/** Die Rückgabe der RETURN-Anweisung. */
	Expression			expression;
	
	/**
	 * Konstruktor.
	 */
	ReturnStatement()
	{
	}
	
	boolean returns()
	{
		return true;
	}
	
	void evaluateExpressions()
	{
		if (expression instanceof IEvaluable)
			expression = ((IEvaluable) expression).eval();
	}
	
	/**
	 * Die Methode führt die Kontextanalyse für diese Anweisung durch.
	 * 
	 * @param declarations
	 *            Die an dieser Stelle gültigen Deklarationen.
	 * @throws CompileException
	 *             Während der Kontextanylyse wurde ein Fehler gefunden.
	 */
	void contextAnalysis(Declarations declarations) throws CompileException
	{
		method = declarations.currentMethod;
		if (expression != null)
		{
			if (declarations.currentMethod.type == null)
				throw new CompileException("Es wird kein Rückgabe-Typ erwartet", null);
			expression = expression.contextAnalysis(declarations);
			expression = expression.box(declarations);
			expression.type.check((ClassDeclaration) declarations.currentMethod.type.declaration, expression.position);
		}
		else
			if (declarations.currentMethod.type != null)
			{
				throw new CompileException("Es wird ein Rückgabe-Typ erwartet", null);
			}
	}
	
	/**
	 * Die Methode gibt diese Anweisung in einer Baumstruktur aus.
	 * 
	 * @param tree
	 *            Der Strom, in den die Ausgabe erfolgt.
	 */
	void print(TreeStream tree)
	{
		tree.println("RETURN");
		if (expression != null)
		{
			tree.indent();
			expression.print(tree);
			tree.unindent();
		}
	}
	
	/**
	 * Die Methode generiert den Assembler-Code für diese Anweisung. Sie geht davon aus, dass die Kontextanalyse vorher
	 * erfolgreich abgeschlossen wurde.
	 * 
	 * @param code
	 *            Der Strom, in den die Ausgabe erfolgt.
	 */
	void generateCode(CodeStream code)
	{
		method.generateExitCode(code, expression);
	}
	
	/**
	 * Die Methode gibt diese Anweisung in Textform aus.
	 */
	@Override
	public String toString()
	{
		return "RETURN " + expression;
	}
}
